package ase.eleitweg.client.gui;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import ase.eleitweg.LocalModule;
import ase.eleitweg.RMIModuleClient;
import ase.eleitweg.TestDBFilledModule;
import ase.eleitweg.TestDBMemoryFilled;
import ase.eleitweg.server.*;
import ase.eleitweg.common.*;
import ase.eleitweg.common.fail.*;


import java.awt.Toolkit;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;

import org.apache.log4j.*;

import com.google.inject.Guice;
import com.google.inject.Injector;



public class Login_gui {
	
	private static final boolean startLocal = false;

	protected Button adminButton = null;
	protected Button userButton = null;
	protected Text benutzernameText;
	protected Text passwortText;
	
	private Logger log = Logger.getLogger(this.getClass());

	protected Shell shell;
	
	private AdminLoginInterface ali;
	private UserLoginInterface uli;
	
	private AdminHandle ah = null;
	private HauptmenueAdmin_gui adminWindow = null;
	
	private Listener globall;

	protected Login_gui() {

		try{
//			Injector injector = Guice.createInjector(new LocalModule(), new TestDBFilledModule());
			Injector injector = Guice.createInjector(new RMIModuleClient());
			ali = injector.getInstance(AdminLoginInterface.class);
			uli = injector.getInstance(UserLoginInterface.class);
		}
		catch(Exception e){
			shell = new Shell(SWT.CLOSE);
			shell.setLayout(new FormLayout());
			Rectangle screenSize = Display.getCurrent().getClientArea();
			shell.setMinimumSize(new Point(350, 200));
			shell.setSize(350, 200);
			shell.setLocation((screenSize.width - shell.getSize().x) / 2,
					(screenSize.height - shell.getSize().y) / 2);
			shell.setVisible(true);
			
			
			shell.setText("Login");
			
			showServerErrorBox();
			System.exit(-1);
		}
	}
	
	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			Login_gui window = new Login_gui();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window
	 */
	public void open() {
		final Display display = Display.getDefault();
		createContents();

		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		System.out.println("exiting");
		if(adminWindow != null) {
			try {
				UnicastRemoteObject.unexportObject(adminWindow, true);
			} catch (NoSuchObjectException e) {
				e.printStackTrace();
				//nothing to do
			}
		}
		
	}

	/**
	 * Create contents of the window
	 */
	protected void createContents() {
		shell = new Shell(SWT.CLOSE);
		shell.setLayout(new FormLayout());
		Rectangle screenSize = Display.getCurrent().getClientArea();
		shell.setMinimumSize(new Point(350, 200));
		shell.setSize(350, 200);
		shell.setLocation((screenSize.width - shell.getSize().x) / 2,
				(screenSize.height - shell.getSize().y) / 2);
		shell.setVisible(true);
		
		
		shell.setText("Login");
		
		final Display display = Display.getCurrent();
		Image icon = new Image(display, "icons/32/agt_web.png");
		shell.setImage(icon);
 
		Label benutzernameLabel;

		Label passwortLabel;

		Button loginButton;
		Button abbrechenButton;
		shell.pack();

		final Composite composite = new Composite(shell, SWT.NONE);
		composite.setLayout(new FormLayout());
		final FormData fd_composite = new FormData();
		fd_composite.left = new FormAttachment(0, 40);
		fd_composite.right = new FormAttachment(0, 315);
		fd_composite.top = new FormAttachment(0, 13);
		fd_composite.bottom = new FormAttachment(0, 80);
		composite.setLayoutData(fd_composite);
		benutzernameLabel = new Label(composite, SWT.NONE);
		final FormData fd_benutzernameLabel = new FormData();
		fd_benutzernameLabel.bottom = new FormAttachment(0, 27);
		fd_benutzernameLabel.top = new FormAttachment(0, 10);
		fd_benutzernameLabel.right = new FormAttachment(0, 104);
		fd_benutzernameLabel.left = new FormAttachment(0, 5);
		benutzernameLabel.setLayoutData(fd_benutzernameLabel);
		benutzernameLabel.setText("Benutzername:");
		benutzernameText = new Text(composite, SWT.BORDER);
		benutzernameText.addFocusListener(new FocusAdapter() {
			public void focusLost(final FocusEvent e) {
				benutzernameText.setSelection(0,benutzernameText.getCharCount());
			}
		});
		benutzernameText.setFocus();
		final FormData fd_benutzernameText = new FormData();
		fd_benutzernameText.right = new FormAttachment(0, 265);
		fd_benutzernameText.bottom = new FormAttachment(0, 32);
		fd_benutzernameText.top = new FormAttachment(0, 5);
		fd_benutzernameText.left = new FormAttachment(0, 109);
		benutzernameText.setLayoutData(fd_benutzernameText);
		passwortLabel = new Label(composite, SWT.NONE);
		final FormData fd_passwortLabel = new FormData();
		fd_passwortLabel.bottom = new FormAttachment(0, 59);
		fd_passwortLabel.top = new FormAttachment(0, 42);
		fd_passwortLabel.right = new FormAttachment(0, 65);
		fd_passwortLabel.left = new FormAttachment(0, 5);
		passwortLabel.setLayoutData(fd_passwortLabel);
		passwortLabel.setText("Passwort:");
		passwortText = new Text(composite, SWT.BORDER | SWT.PASSWORD);
		passwortText.addFocusListener(new FocusAdapter() {
			public void focusLost(final FocusEvent e) {
				passwortText.setSelection(0,passwortText.getCharCount());
			}
		});
		final FormData fd_passwortText = new FormData();
		fd_passwortText.right = new FormAttachment(benutzernameText, 0, SWT.RIGHT);
		fd_passwortText.bottom = new FormAttachment(0, 64);
		fd_passwortText.top = new FormAttachment(0, 37);
		fd_passwortText.left = new FormAttachment(0, 109);
		passwortText.setLayoutData(fd_passwortText);

		final Composite composite_1 = new Composite(shell, SWT.NONE);
		final FormData fd_composite_1 = new FormData();
		fd_composite_1.bottom = new FormAttachment(0, 121);
		fd_composite_1.top = new FormAttachment(0, 95);
		fd_composite_1.right = new FormAttachment(0, 250);
		fd_composite_1.left = new FormAttachment(0, 100);
		composite_1.setLayoutData(fd_composite_1);
		final GridLayout gridLayout_2 = new GridLayout();
		gridLayout_2.numColumns = 2;
		composite_1.setLayout(gridLayout_2);

		userButton = new Button(composite_1, SWT.RADIO);
		userButton.setLayoutData(new GridData());
		userButton.setText("User");
		userButton.setSelection(true);
		
		adminButton = new Button(composite_1, SWT.RADIO);
		final GridData gd_adminButton = new GridData(SWT.CENTER, SWT.CENTER, true, false);
		adminButton.setLayoutData(gd_adminButton);
		adminButton.setText("Admin");

		final Composite composite_2 = new Composite(shell, SWT.NONE);
		final FormData fd_composite_2 = new FormData();
		fd_composite_2.right = new FormAttachment(composite, 0, SWT.RIGHT);
		fd_composite_2.bottom = new FormAttachment(100, -5);
		fd_composite_2.top = new FormAttachment(0, 135);
		fd_composite_2.left = new FormAttachment(0, 90);
		composite_2.setLayoutData(fd_composite_2);
		final GridLayout gridLayout_1 = new GridLayout();
		gridLayout_1.numColumns = 2;
		composite_2.setLayout(gridLayout_1);
		loginButton = new Button(composite_2, SWT.NONE);

		globall = new Listener() {
				public void handleEvent(Event event) {
                if(event.keyCode == 13) {
                	display.removeFilter(SWT.KeyDown, globall);
                	processLogin();
                }
                if(event.keyCode == 27) {
                	shell.close();
                }
            }
        };
		display.addFilter(SWT.KeyDown, globall );
 
		loginButton.setLayoutData(new GridData(80, SWT.DEFAULT));
		loginButton.addMouseListener(new MouseAdapter() {
			public void mouseDown(final MouseEvent e) {
				display.removeFilter(SWT.KeyDown, globall);
				processLogin();
			}
		});
		loginButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				display.removeFilter(SWT.KeyDown, globall);
				processLogin();
			}
		});
		
		loginButton.setText("Login");
		abbrechenButton = new Button(composite_2, SWT.NONE);
		
		abbrechenButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				shell.close();
			}
		});

		abbrechenButton.setLayoutData(new GridData(80, SWT.DEFAULT));
		abbrechenButton.addMouseListener(new MouseAdapter() {
			public void mouseDown(final MouseEvent e) {
				shell.close();
			}
		});
		
		

		abbrechenButton.setText("Abbrechen");
	}
	
	public void processLogin() {
		try {
			if (adminButton.getSelection()) {

				if (ali != null) {
					ServerAdminHandle sah = ali
							.login(benutzernameText.getText(), User
									.getMD5Hash(passwortText.getText()));
					adminWindow = new HauptmenueAdmin_gui(sah);
					ah = (AdminHandle) UnicastRemoteObject.exportObject(
							adminWindow, 0);
					if (!ali.checkUnique(ah)) {
						MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
						box.setText("Fehler");
						box.setMessage("Es ist bereits ein Admin eingeloggt.");
						box.open();
						return;
					}
					System.out.println("authorisation passed");
					shell.close();
					adminWindow.open();
				} else {
					showServerErrorBox();
				}

			} else {

				if (uli == null) {
					showServerErrorBox();
				} else {
					ServerUserHandle suh = uli.login(
							benutzernameText.getText(), User
									.getMD5Hash(passwortText.getText()));

					User me = uli.getMe(benutzernameText.getText(), User
							.getMD5Hash(passwortText.getText()));
					HauptmenueClient_gui window = new HauptmenueClient_gui(suh,
							me);
					System.out.println("authorisation passed");
					shell.close();
					window.open();
				}

			}
		} catch (AuthorisationException ae) {
			MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
			box.setMessage("Falsche Eingabe");
			box.setText("Error");
			box.open();
			final Display display = Display.getCurrent();
			globall = new Listener() {
				public void handleEvent(Event event) {
					if (event.keyCode == 13) {
						display.removeFilter(SWT.KeyDown, globall);
						processLogin();
					}
					if (event.keyCode == 27) {
						shell.close();
					}
				}
			};
			return;
		} catch (RemoteException re) {
			re.printStackTrace();
		}

	}
	
	private void showServerErrorBox(){
		MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
		box.setMessage("Server nicht gefunden!");
		box.setText("Error");
		box.open();
	}

}
